查看原文
其他

CVE-2017-10661 原理,触发分析

2017-08-25 小白君 看雪学院


前言



最近分析了 CVE-2017-10661 这个漏洞,不过没有找到什么可以利用的点。把分析过程拿出来分享下。首先看看官方的修补代码:



上面是官方的修补代码, 可以很直观的看到,修补代码主要做了几件事:

  • 首先在结构体里面添加了一个锁的成员变量,

  • 然后在代码中上了锁


从这两个结论,首先就可以基本推论出来,这个漏洞应该是多线程并行,导致出来的问题。


接着继续分析修补代码,我们发现上锁的代码主要在 一下代码:



这样看不太方便,感觉有点混乱,我把这个函数从源码中找出来了



结合两段代码,我们可以看到:主要是给中间的这一段代码上了锁。那么主要问题就是出现在这一段代码当中了。


这两条分支:上面是链表添加结点;下面是移除。


两条路线分支主要是 ctx->might_cancel 这个成员变量判断的。


然后我们发现:这个变量,他是会在分支的运行过程里面修改的,蓝色的标记代码就是修改的地点。


那么我们根据上面得到的信息,可以得到一个假设:


如果两条线程同时运行这一段代码


❶ 线程1 删除了结点  并且 ctx->might_cancel = false; 那么他下次再运行的到这里的时候:

这个条件就不会成立,那么就不会运行 timerfd_remove_cancel 函数。


以上是正常情况,现在我们假设一中特殊情况


线程1 第二次执行到  else if (ctx->might_cancel) 这里的时候,CPU进行切换,切换到线程2执行。


❷ 线程2  走上面分支



设置了 ctx->might_cancel = true; 然后CPU继续执行线程1


现在 ctx->might_cancel 被线程2修改成了 true 又会执行 timerfd_remove_cancel



那么现在 timerfd_remove_cancel(ctx); 删除了两次结点 这就是漏洞的产生原理。


利用


如果猜测是对的,那么我们创建两条线程, 一条循环执行删除操作,一个执行添加操作,就会触发到漏洞。


测试过后,成功触发了漏洞。


注:看了下代码本身流程,这里删除结点,只是想节点的上下两个点的指向修改了下。


崩溃的主要原因是因为,entry->prev = LIST_POISON2;  这里执行到第二次的时候,尝试在 LIST_POISON2 写入内容,导致了崩溃。


测试机器


  • nexus5  5.0  hammerhead-lrx21o-factory-56a09d43 版本

  • 附带代码: NDK-12-windows 编译







本文由看雪论坛 小白君 原创

转载请注明来自看雪社区



热门阅读


点击阅读原文/read,

更多干货等着你~




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存